/**
 * 
 */
package com.thinkgsp.jxc.model;

import java.io.Serializable;
import java.math.BigDecimal;
import java.sql.Date;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;

import com.fasterxml.jackson.annotation.JsonIgnore;

/**
 * 单据类
 * @author evan
 *
 */
public abstract class Bill extends BaseModel implements Serializable {

	private static final long serialVersionUID = 5089453396585994822L;

	private Long billId;
	private String billCode;
	private Date billDate = new Date(System.currentTimeMillis());
	private Integer custId;
	private Integer billType;
	private String billName;
	private Integer direct;
	private Integer deptId;
	private Integer empId;
	private Integer makerId;
	private Integer status = 0;
	private Integer fyear;
	private Integer period;
	private Boolean archived = false;
	private Boolean deleted = false;
	private String remark;
	
	private List<BillDetail> details = new ArrayList<BillDetail>();
	private int detailIndex = -1;
	private BillExtend billExtend;
	private Customer customer;
	private Dept dept;
	private Emp emp;
	private Emp maker;
	private BillAmount billAmount;// = new BillAmount();

	/**
	 * 创建单据明细
	 * @return
	 */
	public abstract BillDetail createDetail();
	/**
	 * 单据ID
	 * @return
	 */
	public Long getBillId() {
		return billId;
	}

	public void setBillId(Long billId) {
		this.billId = billId;
	}

	/**
	 * 单据编码(可以为空)，已单据ID为主
	 * @return
	 */
	public String getBillCode() {
		return billCode;
	}

	public void setBillCode(String billCode) {
		this.billCode = billCode;
	}

	/**
	 * 单据日期
	 * @return
	 */
	public Date getBillDate() {
		return billDate;
	}

	/**
	 * 单据日期
	 * @param billDate
	 */
	public void setBillDate(Date billDate) {
		this.billDate = billDate;
	}

	/**
	 * 客户ID
	 * @return
	 */
	public Integer getCustId() {
		return custId;
	}

	public void setCustId(Integer custId) {
		this.custId = custId;
	}

	/**
	 * 单据类型
	 * 正数为入库单据;负数为出库单据; 
	 * 其中 1 代表产品入库单;2入库退出单;3代表其他入库单;4代表差价单
	 * -1代表产品出库单;-2出库退回单;-3代表其他出库单;-4代表差价单
	 * @return
	 */
	public Integer getBillType() {
		return billType;
	}

	public void setBillType(Integer billType) {
		this.billType = billType;
	}

	/**
	 * 其他单据名称
	 * @return
	 */
	public String getBillName() {
		return billName;
	}

	public void setBillName(String billName) {
		this.billName = billName;
	}

	/**
	 * 单据出入库方向
	 * 1 代表入库; -1代表出库;
	 * 0代表未确定，必须有单据明细的direct决定
	 * @return
	 */
	public Integer getDirect() {
		return direct;
	}

	public void setDirect(Integer direct) {
		this.direct = direct;
	}

	/**
	 * 开单部门
	 * @return
	 */
	public Integer getDeptId() {
		return deptId;
	}

	public void setDeptId(Integer deptId) {
		this.deptId = deptId;
	}

	/**
	 * 业务员
	 * @return
	 */
	public Integer getEmpId() {
		return empId;
	}

	public void setEmpId(Integer empId) {
		this.empId = empId;
	}

	/**
	 * 制单人
	 * @return
	 */
	public Integer getMakerId() {
		return makerId;
	}

	public void setMakerId(Integer makerId) {
		this.makerId = makerId;
	}

	/**
	 * 单据状态
	 * @return
	 */
	public Integer getStatus() {
		return status;
	}

	public void setStatus(Integer status) {
		this.status = status;
	}

	/**
	 * 年
	 * @return
	 */
	public Integer getFyear() {
		return fyear;
	}

	public void setFyear(Integer fyear) {
		this.fyear = fyear;
	}

	/**
	 * 期间
	 * @return
	 */
	public Integer getPeriod() {
		return period;
	}

	public void setPeriod(Integer period) {
		this.period = period;
	}

	/**
	 * 归档标志(代表已经出入库以及记账)
	 * @return
	 */
	public Boolean getArchived() {
		return archived;
	}

	public void setArchived(Boolean archived) {
		this.archived = archived;
	}

	/**
	 * 备注
	 * @return
	 */
	public String getRemark() {
		return remark;
	}

	public void setRemark(String remark) {
		this.remark = remark;
	}

	public Boolean getDeleted() {
		return deleted;
	}

	public void setDeleted(Boolean deleted) {
		this.deleted = deleted;
	}

	/**
	 * 单据明细列表
	 * @return
	 */
	public List<BillDetail> getDetails() {
		return details;
	}

	public void setDetails(List<BillDetail> details) {
		this.details = details;
	}

	/**
	 * 单据扩展
	 * @return
	 */
	public BillExtend getBillExtend() {
		return billExtend;
	}

	public void setBillExtend(BillExtend billExtend) {
		this.billExtend = billExtend;
	}

	/**
	 * 单据客户
	 * @return
	 */
	public Customer getCustomer() {
		return customer;
	}

	public void setCustomer(Customer customer) {
		this.customer = customer;
		this.custId = customer.getCustomerId();
	}

	/**
	 * 部门
	 * @return
	 */
	public Dept getDept() {
		return dept;
	}

	public void setDept(Dept dept) {
		this.dept = dept;
		this.deptId = dept.getDeptId();
	}

	/**
	 * 业务员
	 * @return
	 */
	public Emp getEmp() {
		return emp;
	}

	public void setEmp(Emp emp) {
		this.emp = emp;
		this.empId = emp.getEmpId();
	}

	/**
	 * 制单人
	 * @return
	 */
	public Emp getMaker() {
		return maker;
	}

	public void setMaker(Emp maker) {
		this.maker = maker;
		this.makerId = maker.getEmpId();
	}

	public BillAmount getBillAmount() {
		return billAmount;
	}

	public void setBillAmount(BillAmount billAmount) {
		this.billAmount = billAmount;
	}

	/* (non-Javadoc)
	 * @see com.thinkgsp.jxc.model.BaseModel#toString()
	 */
	@Override
	public String toString() {
		ToStringBuilder sb = new ToStringBuilder(this, ToStringStyle.DEFAULT_STYLE);
		sb.append("id",this.billId)
		  .append("billCode",this.billCode)
		  .append("billName",this.billName);
		
		return sb.toString();
	}

	/* (non-Javadoc)
	 * @see com.thinkgsp.jxc.model.BaseModel#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object o) {
		if(this == o) {
			return true;
		}
		if(!(o instanceof Bill)) {
			return false;
		}
		final Bill bill = (Bill)o;
		if(billId != null) {
			return billId.equals(bill.getBillId());
		} else {
			return bill.getBillId() == null;
		}
	}

	/* (non-Javadoc)
	 * @see com.thinkgsp.jxc.model.BaseModel#hashCode()
	 */
	@Override
	public int hashCode() {
		return (this.billId != null ? this.billId.hashCode() : 0);
	}
	/**
	 * @return the currDetail
	 */
	@JsonIgnore
	public BillDetail getCurrDetail() {
		return details.get(detailIndex);
	}
	
	public void setCurrDetail(BillDetail detail) {
		
	}
	/**
	 * @return the detailIndex
	 */
	public int getDetailIndex() {
		return detailIndex;
	}
	/**
	 * @param detailIndex the detailIndex to set
	 */
	public void setDetailIndex(int detailIndex) {
		this.detailIndex = detailIndex;
	}
	
	public BillAmount recalcBillAmount(){
		if(this.billAmount==null){
			this.billAmount=new BillAmount();
		}
		BigDecimal sum=BigDecimal.ZERO;
		BigDecimal setSum=BigDecimal.ZERO;
		BigDecimal cost=BigDecimal.ZERO;
		for (BillDetail detail : this.details) {
			sum.add(detail.getAmount());
			setSum.add(detail.getQuantity().multiply(detail.getSettlePrice()));
			cost.add(detail.getQuantity().multiply(detail.getCostPrice()));
		}
		this.billAmount.setBillAmount(sum);
		this.billAmount.setBillSettleAmount(setSum);
		this.billAmount.setBillCostAmount(cost);
		return this.billAmount;
	}
}
